package com.collabscm.md.base.service.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.commons.collections.map.MultiKeyMap;
import org.springframework.stereotype.Service;

import com.collabscm.md.base.model.Parameter;
import com.collabscm.pf.dao.support.DomainDaoFactory;
import com.collabscm.pf.exception.ConfigurationException;
import com.collabscm.pf.logging.Logger;
import com.collabscm.pf.logging.LoggerFactory;
import com.collabscm.pf.profiler.Monitor;
import com.collabscm.pf.util.ConstantUtils;
import com.collabscm.pf.util.ConstantUtils.ConstantProvider;

/**
 * 数据库方式提供的常量定义
 *
 * @author Zeng Raoxing
 */
@Service(ConstantUtils.constantProviderName)
public class MasterdataConstantProvider extends ConstantProvider {
	private Logger logger = LoggerFactory.getLogger(MasterdataConstantProvider.class);
	@Override
	@Monitor(uptime=20)
	public Integer findConstant(String constantCategory, String constantCode) {
		checkConstants();
		Integer parameterId = (Integer) constantMap.get(constantCategory, constantCode);
		if(parameterId == null) {
			StringBuffer sb = new StringBuffer("未找到(constantCategory=").append(constantCategory);
			sb.append(", constantCode=").append(constantCode).append(")的常量。\n");
			sb.append("可能的原因：1、可能未在T_MD_Parameter中定义插入相应的数据；\n\t2、也可能是此数据已经过期或失效，即现在已经不需要使用；\n\t3、还有可能在系统中定义了多个取值相同的常量，请检查程序。");
			throw new ConfigurationException(sb.toString());
		}
		constantMap.remove(constantCategory, constantCode);
		logger.info("(constantCategory={},constantCode={})对应的ID为{}", constantCategory, constantCode, parameterId);
		return parameterId;
	}
	/**
	 * 常量数据是否从数据库中load完毕？
	 */
	private boolean loaded;
	/**
	 * 存放所有当前还未被取完的常量定义
	 */
	private MultiKeyMap constantMap;
	
	@SuppressWarnings("unchecked")
	private void checkConstants() {
		if(!loaded) {
			EntityManager em = DomainDaoFactory.getEntityManager();
			Query query = em.createNamedQuery(Parameter.findBusinessContantsName);
			List<Parameter.Constant> constants = query.getResultList();
			constantMap = new MultiKeyMap();
			for(Parameter.Constant constant: constants) {
				constantMap.put(constant.getParameterCategory(), constant.getParameterCode(), constant.getParameterId());
			}
			loaded = true;
			logger.debug("常量数据从数据库中load完毕！共加载出{}条常量定义。", constants.size());
		}
		
	}

}
